<html>
<title>ARM9 syscall functions available in SNUVM
</title>
<style type="text/css"> 
/* default css */
table {
font-size: 1em;
line-height: inherit;
border-collapse: collapse;
}
tr {
text-align: left;
}
div, address, ol, ul, li, option, select {
margin-top: 0px;
margin-bottom: 0px;
}
p {
margin: 0px;
}
pre {
font-family: Courier New;
white-space: pre-wrap;
margin:0;
}
body {
margin: 6px;
padding: 0px;
font-family: Verdana, sans-serif;
font-size: 10pt;
background-color: #ffffff;
}
img {
-moz-force-broken-image-icon: 1;
}
@media screen {
html.pageview {
background-color: #f3f3f3 !important;
overflow-x: hidden;
overflow-y: scroll;
}
body {
min-height: 1100px;
counter-reset: __goog_page__;
}
* html body {
height: 1100px;
}
.pageview body {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 2px solid #bbb;
border-bottom: 2px solid #bbb;
width: 648px !important;
margin: 15px auto 25px;
padding: 40px 50px;
}
/* IE6 */
* html {
overflow-y: scroll;
}
* html.pageview body {
overflow-x: auto;
}
/* Prevent repaint errors when scrolling in Safari. This "Star-7" css hack
targets Safari 3.1, but not WebKit nightlies and presumably Safari 4.
That's OK because this bug is fixed in WebKit nightlies/Safari 4 :-). */
html*#wys_frame::before {
content: '\A0';
position: fixed;
overflow: hidden;
width: 0;
height: 0;
top: 0;
left: 0;
}
.writely-callout-data {
display: inline-block;
width: 1px;
height: 1px;
overflow: hidden;
margin-left: -1px;
}
.writely-footnote-marker {
background-image: url('images/footnote_doc_icon.gif');
background-color: transparent;
background-repeat: no-repeat;
width: 7px;
overflow: hidden;
height: 16px;
vertical-align: top;
-moz-user-select: none;
}
.editor .writely-footnote-marker {
cursor: move;
}
.writely-footnote-marker-highlight {
background-position: -15px 0;
-moz-user-select: text;
}
.writely-footnote-hide-selection ::-moz-selection, .writely-footnote-hide-selection::-moz-selection {
background: transparent;
}
.writely-footnote-hide-selection ::selection, .writely-footnote-hide-selection::selection {
background: transparent;
}
.writely-footnote-hide-selection {
cursor: move;
}
/* Comments */
.writely-comment-yellow {
background-color: #ffffd7;
}
.writely-comment-orange {
background-color: #ffe3c0;
}
.writely-comment-pink {
background-color: #ffd7ff;
}
.writely-comment-green {
background-color: #d7ffd7;
}
.writely-comment-blue {
background-color: #d7ffff;
}
.writely-comment-purple {
background-color: #eed7ff;
}
.br_fix span+br:not(:-moz-last-node) {
position:relative;
left: -1ex
}
#cb-p-tgt {
font-size: 8pt;
padding: .4em;
background-color: #ddd;
color: #333;
}
#cb-p-tgt-can {
text-decoration: underline;
color: #36c;
font-weight: bold;
margin-left: 2em;
}
#cb-p-tgt .spin {
width: 16px;
height: 16px;
background: url(//ssl.gstatic.com/docs/clipboard/spin_16o.gif) no-repeat;
}
}
h6 { font-size: 8pt }
h5 { font-size: 8pt }
h4 { font-size: 10pt }
h3 { font-size: 12pt }
h2 { font-size: 14pt }
h1 { font-size: 18pt }
blockquote {padding: 10px; border: 1px #DDD dashed }
.webkit-indent-blockquote { border: none; }
a img {border: 0}
.pb {
border-width: 0;
page-break-after: always;
/* We don't want this to be resizeable, so enforce a width and height
using !important */
height: 1px !important;
width: 100% !important;
}
.editor .pb {
border-top: 1px dashed #C0C0C0;
border-bottom: 1px dashed #C0C0C0;
}
div.google_header, div.google_footer {
position: relative;
margin-top: 1em;
margin-bottom: 1em;
}
/* Table of contents */
.editor div.writely-toc {
background-color: #f3f3f3;
border: 1px solid #ccc;
}
.writely-toc > ol {
padding-left: 3em;
font-weight: bold;
}
ol.writely-toc-subheading {
padding-left: 1em;
font-weight: normal;
}
/* IE6 only */
* html writely-toc ol {
list-style-position: inside;
}
.writely-toc-none {
list-style-type: none;
}
.writely-toc-decimal {
list-style-type: decimal;
}
.writely-toc-upper-alpha {
list-style-type: upper-alpha;
}
.writely-toc-lower-alpha {
list-style-type: lower-alpha;
}
.writely-toc-upper-roman {
list-style-type: upper-roman;
}
.writely-toc-lower-roman {
list-style-type: lower-roman;
}
.writely-toc-disc {
list-style-type: disc;
}
/* Ordered lists converted to numbered lists can preserve ordered types, and
vice versa. This is confusing, so disallow it */
ul[type="i"], ul[type="I"], ul[type="1"], ul[type="a"], ul[type="A"] {
list-style-type: disc;
}
ol[type="disc"], ol[type="circle"], ol[type="square"] {
list-style-type: decimal;
}
/* end default css */
/* custom css */
/* end custom css */
/* ui edited css */
body {
font-family: Verdana;
font-size: 10.0pt;
line-height: normal;
background-color: #ffffff;
}
/* end ui edited css */
/* editor CSS */
.editor a:visited {color: #551A8B}
.editor table.zeroBorder {border: 1px dotted gray}
.editor table.zeroBorder td {border: 1px dotted gray}
.editor table.zeroBorder th {border: 1px dotted gray}
.editor div.google_header, .editor div.google_footer {
border: 2px #DDDDDD dashed;
position: static;
width: 100%;
min-height: 2em;
}
.editor .misspell {background-color: yellow}
.editor .writely-comment {
font-size: 9pt;
line-height: 1.4;
padding: 1px;
border: 1px dashed #C0C0C0
}
/* end editor CSS */
</style> 
<style> 
body {
margin: 0px;
}
#doc-contents {
margin: 6px;
}
#google-view-footer {
clear: both;
border-top: thin solid;
padding-top: 0.3em;
padding-bottom: 0.3em;
}
a.google-small-link:link, a.google-small-link:visited {
color:#112ABB;
font-family:Arial,Sans-serif;
font-size:11px !important;
}
body, p, div, td {
direction: inherit;
}
@media print {
#google-view-footer {
display: none;
}
}
</style> 
<body>
<center>
<h3>SYSCALL functions available in SNUVM</h3>
</center>

<h3>Introduction</h3>
A number of system services, mainly for input and output, are available for use by 
your ARM9 program.  They are described in the table below.
<p>
<h3>How to use SYSCALL system services</h3>
Step 1. Load argument values, if any, in r4, r5, r6, or r7 as specified.<br>
Step 2. Issue the SYSCALL instruction with system calls number followed by '#'.<br>
Step 3. Retrieve return values, if any, from result registers as specified.
</p>
<br><br>
<pre>
    Example: display the value stored in r4 on the console

    mov r4, #7		@ load desired value into argument register r4, using pseudo-op
    swi #1		@ service 1 is print integer
</pre>
<br>
<h3>Table of Available Services</h3>
<div id="doc-contents"> 
<div></div><div><table id="jek:" width="95%" cellpadding="1" cellspacing="1" border="1" class="" bordercolor="#000000"><tbody><tr style="text-align: left"><td width="20%" bgcolor="#d0e0e3" style="text-align: center"><font size="3">Service</font></td><td width="20%" bgcolor="#d0e0e3" style="text-align: center"><font size="3">System call code</font></td><td width="20%" bgcolor="#d0e0e3" style="text-align: center"><font size="3">Arguments</font></td><td width="20%" bgcolor="#d0e0e3" style="text-align: center"><font size="3">Result</font></td><td width="20%" bgcolor="#d0e0e3" style="text-align: center"><font size="3">Remarks</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">print_int</font></td><td width="10%" align="center"><font size="3">1</font></td><td width="20%"><font size="3">r4=integer</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">print_float</font></td><td width="20%" align="center"><font size="3">2</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">print_double</font></td><td width="20%" align="center"><font size="3">3</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">print_string</font></td><td width="20%" align="center"><font size="3">4</font></td><td width="20%"><font size="3">r4=string address</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read_int</font></td><td width="20%" align="center"><font size="3">5</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">integer(in r4)</font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read_float</font></td><td width="20%" align="center"><font size="3">6</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read_double</font></td><td width="20%" align="center"><font size="3">7</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read_string</font></td><td width="20%" align="center"><font size="3">8</font></td><td width="20%"><font size="3">r4=buffer,<br>r5=length</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">sbrk</font></td><td width="20%" align="center"><font size="3">9</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">exit</font></td><td width="20%" align="center"><font size="3">10</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">print_char</font></td><td width="20%" align="center"><font size="3">11</font></td><td width="20%"><font size="3">r4=char</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read_char&nbsp;</font></td><td width="20%" align="center"><font size="3">12</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">char(in r4)</font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">open</font></td><td width="20%" align="center"><font size="3">13</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">read</font></td><td width="20%" align="center"><font size="3">14</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">write</font></td><td width="20%" align="center"><font size="3">15</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">close</font></td><td width="20%" align="center"><font size="3">16</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">exit2</font></td><td width="20%" align="center"><font size="3">17</font></td><td width="20%"><font size="3">r4=result</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">time</font></td><td width="20%" style="text-align: center"><font size="3">30</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">midiOut&nbsp;</font></td><td width="20%" style="text-align: center"><font size="3">31</font></td><td width="20%"><font size="3">r4=pitch (0-127)<br>r5=duration in milliseconds&nbsp;<br>r6=instrument (0-127)&nbsp;<br>r7=volume (0-127)</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">generates the tone then immediately return(Note that this service should be combined to service 32, if not, program terminate illegally)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">sleep</font></td><td width="20%" align="center"><font size="3">32</font></td><td width="20%"><font size="3">r4=the length of time to sleep in milliseconds</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">midiOutSync</font></td><td width="20%" align="center"><font size="3">33</font></td><td width="20%"><font size="3">r4=pitch (0-127)<br>r5=duration in milliseconds&nbsp;<br>r6=instrument (0-127)&nbsp;<br>r7=volume (0-127)</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">generates the tone then sleep for the tone's duration before returning. Thus it essentially combines services 31 and 32</font></td></tr><tr style="text-align: left"><td width="20%"><div><font size="3">randSeed</font></div></td><td width="20%" align="center"><font size="3">40</font></td><td width="20%"><font size="3">r4 = i.d. of pseudorandom number generator (any int).&nbsp;<br>r5 = seed for corresponding pseudorandom number generator</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">No values are returned. Sets the seed of the corresponding underlying Java pseudorandom number generator (java.util.Random). See note below table</font></td></tr><tr style="text-align: left"><td width="20%"><div><font size="3">randInt</font></div></td><td width="20%" align="center"><font size="3">41</font></td><td width="20%"><font size="3">r4 = i.d. of pseudorandom number generator (any int)</font></td><td width="20%"><font size="3">integer(in r4)</font></td><td width="20%"><font size="3">r4 contains the next pseudorandom, uniformly distributed int value from this random number generator's sequence. See note below table</font></td></tr><tr style="text-align: left"><td width="20%"><div><font size="3">randIntRange</font></div></td><td width="20%" align="center"><font size="3">42</font></td><td width="20%"><div><font size="3">r4= i.d. of pseudorandom number generator (any int)</font></div><div><font size="3">r5 = upper bound of range of returned values</font></div></td><td width="20%"><font size="3">integer(in r4)</font></td><td width="20%"><font size="3">r4 contains pseudorandom, uniformly distributed int value in the range 0 = [int] [upper bound], drawn from this random number generator's sequence. See note below table</font></td></tr><tr style="text-align: left"><td width="20%"><div><font size="3">randFloat</font></div></td><td width="20%" align="center"><font size="3">43</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">randDouble &nbsp;</font></td><td width="20%" align="center"><font size="3">44</font></td><td width="20%"></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">(N/A)</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">videoOutOn</font></td><td width="20%" align="center"><font size="3">45</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3">refresh rate = &nbsp;30Hz</font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">videoOutOff</font></td><td width="20%" style="text-align: center"><font size="3">46</font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td><td width="20%"><font size="3"><br></font></td></tr><tr style="text-align: left"><td width="20%"><font size="3">intToString</font></td><td width="20%" style="text-align: center"><font size="3">47</font></td><td width="20%"><font size="3">r4=value<br>r5=buffer<br>r6=length in byte</font></td><td width="20%"><font size="3">string (in r5)<br></font></td><td width="20%"><font size="3"><br></font></td></tr></tbody></table></div><br> 
<br clear="all"/> 
</div> 
<b>NOTES: Services numbered 45 and higher are not provided by MARS or SPIM</b><br>
<br><b>Service 8</b> - Follows semantics of UNIX 'fgets'.  For specified length n, string can be no longer than n-1. If less than that, adds newline to end.  In either case, then pads with null byte.
<br><b>Service 11</b> - Prints ASCII character corresponding to contents of low-order byte.
<br><b>Service 13</b> - SNUVM implements three flag values: 0 for read-only, 1 for write-only with create, and 9 for write-only with create and append.  It ignores mode.  The returned file descriptor will be negative if the operation failed.  The underlying file I/O
implementation uses <tt>java.io.FileInputStream.read()</tt> to read and <tt>java.io.FileOutputStream.write()</tt> to write.  SNUVM maintains file descriptors internally and allocates them starting with 0.
<br><b>Services 13,14,15</b> - In SNUVM 3.7, the result register was changed to $v0 for SPIM compatability.  It was previously r4 as erroneously printed
in Appendix B of <i>Computer Organization and Design,</i>.
<br><b>Service 17</b> - If the ARM9 program is run under control of the SNUVM graphical interface (GUI), the exit code in r4 is ignored.
<br><b>Service 30</b> - System time comes from <tt>java.util.Date.getTime()</tt> as milliseconds since 1 January 1970.
<br><b>Services 31,33</b> - Simulate MIDI output through sound card.  Details below.
<br><b>Services 40-44</b> use underlying Java pseudorandom number generators provided by the <tt>java.util.Random</tt> class.  Each stream (identified
by r4 contents) is modeled by a different <tt>Random</tt> object.  There are no default seed values, so use the Set Seed service (40) if 
replicated random sequences are desired.
<br><b>Services 45,46</b> - Simulate Video output through video card.  Details below.

<p></p>
<hr>
<h3>Example of I/O</h3>
Compute first twelve Fibonacci numbers and put in array, then print (standard I/O)
<p>
<pre>
@ Program Description: 
@
@ SNUVM is Seoul National University Assembly-executable Virtual Machine.
@ It assembles several kinds of assembly source files(such as ARM9 and MIPS)
@ and interprets output with built-in OS system-call services.
@ SNUVM is written in Java with eclipse and requires
@ at least Release 1.4 of the J2SE Java Runtime Environment(JRE) to work.
@
@ Author: Jaejin Lee, Jeongho Nah
@ License: MIT License
@ Creation Date: 2009-12-17
@ Revisions: 0
@   -Date: 				-Modified by: 
@
@ Remark:
@	SNUVM was extended from MARS.
@	"MARS Copyright (c) 2003-2009,  Pete Sanderson and Kenneth Vollmar"
@
@===================================
@ ASSEMBLER TEST CODE
@ 17th February 2010
@ Compute first twelve Fibonacci numbers and put in array, then print
@===================================
      .code32

@ r0=array index, r1=counter
		adr r0, fibs		@ load address of array
		ldr r1, size		@ load array size
		mov r2, #1			@ 1 is first and second Fibonacci number
		str r2, [r0]		@ F[0] = 1
		add r0, r0, #4
		str r2, [r0]		@ F[1] = F[0] = 1
		sub r0, r0, #4
		sub r1, r1, #2			@ Counter for loop, will execute (size-2) times

loop:	ldr r3, [r0]		@ Get value from array F[n] 
		add r4, r0, #4
		ldr r4, [r4]		@ Get value from array F[n+1]
		add r3, r3, r4			@ r3 = F[n] + F[n+1]
		mov r4, #1
		mov r4, r4, lsl #3			@ r4 = 8
		add r4, r4, r0
		str r3, [r4]		@ Store F[n+2] = F[n] + F[n+1] in array
		add r0, r0, #4		@ increment address of Fib. number source
		sub r1, r1, #1		@ decrement loop counter
		cmp r1, #0
		bne loop

		adr r0, fibs
		adr r1, size 		@ load address of size variable
		ldr r1, [r1]		@ load array size
		
		bl print

		swi #10				@ system call for exit

@@@@@@@@  routine to print the numbers on one line. 

print:	adr r4, head 		@ load address of print heading
		swi #4				@ specify Print String service

out:	ldr r4, [r0]		@ load fibonacci number for syscall
		swi #1				@ specify Print Integer service
		adr r4, space
      	swi #4
		add r0, r0, #4		@ increment address
		sub r1, r1, #1		@ decrement loop counter
		cmp r1, #0
		bne out
		mov r15, r14		@ return

		.data
fibs: .word   0 : 12        @ "array" of 12 words to contain fib values
size: .word  12             @ size of "array" 

space:.asciiz  " "          @ space to insert between numbers
head: .asciiz  "The Fibonacci numbers are:\n"
</pre>

<p></p>
<hr>
<h3>Using SYSCALL system services 31 and 33: MIDI output</h3>
These system services are unique to SNUVM, and provide a means of producing sound.  MIDI output is
simulated by your system sound card, and the simulation is provided by the <tt>javax.sound.midi</tt>
package.  
<p>Service 31 will generate the tone then immediately return.  Service 33 will generate the tone then
sleep for the tone's duration before returning.  Thus it essentially combines services 31 and 32.
<p>
This service requires four parameters as follows:

<table width="600" border="0" align="center" cellpadding="2">
  <tr>
    <td><h3>pitch (r4)</h3>
        
      <li>Accepts a positive byte value (0-127) that denotes a pitch as it would 
        be represented in MIDI </li>
        
      <li>Each number is one semitone / half-step in the chromatic scale.</li>
        
      <li>0 represents a very low C and 127 represents a very high G (a standard 
        88 key piano begins at 9-A and ends at 108-C).</li>
      <li>If the parameter value is outside this range, it applies a default value 60 which is the same as middle C on a piano.</li>
        
      <li>From middle C, all other pitches in the octave are as follows:</li>
      
        
      <table width="450" border="0" align="center" cellpadding="2">
        <tr>
            <td>
        	 <li>61 = C# or Db</li>
        	 <li>62 = D</li>
        	 <li>63 = D# or Eb</li>
        	 <li>64 = E or Fb</li>
			</td>
            <td>
        	 <li>65 = E# or F</li>
        	 <li>66 = F# or Gb</li>
        	 <li>67 = G</li>
        	 <li>68 = G# or Ab</li>
			</td>
            <td>
			 <li>69 = A</li>
        	 <li>70 = A# or Bb</li>
        	 <li>71 = B or Cb</li>
        	 <li>72 = B# or C</li>
			</td>
          </tr>
        </table>
        
        
      <li>To produce these pitches in other octaves, add or subtract multiples 
        of 12.</li>
      <br>
      </td>
  </tr>
  <tr>
    <td><h3>duration in milliseconds (r5)</h3>
      <li>Accepts a positive integer value that is the length of the tone in milliseconds.</li>
      <li>If the parameter value is negative, it applies a default value of one second (1000 milliseconds).</li>
      <br>
    </td>
  </tr>
  <tr>
    <td><h3>instrument (r6)</h3>
	  <li>Accepts a positive byte value (0-127) that denotes the General MIDI 
        &quot;patch&quot; used to play the tone.</li>
      <li>If the parameter is outside this range, it applies a default value 0 which is an <em>Acoustic Grand Piano</em>.</li>
      <li>General MIDI standardizes the number associated with each possible instrument 
        (often referred to as <em>program change</em> numbers), however it does 
        not determine how the tone will sound. This is determined by the synthesizer 
        that is producing the sound. Thus a<em> Tuba</em> (patch 58) on one computer 
        may sound different than that same patch on another computer.</li>
      <li>The 128 available patches are divided into instrument families of 8:</li>
	  <table width="450" border="0" align="center" cellpadding="2">
        <tr> 
          <td width="60">0-7</td>
          <td width="160">Piano</td>
          <td width="60">64-71</td>
          <td>Reed</td>
        </tr>
        <tr> 
          <td width="60">8-15</td>
          <td width="160">Chromatic Percussion</td>
          <td width="60">72-79</td>
          <td>Pipe</td>
        </tr>
        <tr> 
          <td width="60">16-23</td>
          <td width="160">Organ</td>
          <td width="60">80-87</td>
          <td>Synth Lead</td>
        </tr>
        <tr> 
          <td width="60">24-31</td>
          <td width="160">Guitar</td>
          <td width="60">88-95</td>
          <td>Synth Pad</td>
        </tr>
        <tr> 
          <td width="60">32-39</td>
          <td width="160">Bass</td>
          <td width="60">96-103</td>
          <td>Synth Effects</td>
        </tr>
        <tr> 
          <td width="60">40-47</td>
          <td width="160">Strings</td>
          <td width="60">104-111</td>
          <td>Ethnic</td>
        </tr>
        <tr> 
          <td width="60">48-55</td>
          <td width="160">Ensemble</td>
          <td width="60">112-119</td>
          <td>Percussion</td>
        </tr>
        <tr> 
          <td width="60">56-63</td>
          <td width="160">Brass</td>
          <td width="60">120-127</td>
          <td>Sound Effects</td>
        </tr>
      </table>
      <li>Note that outside of Java, General MIDI usually refers to patches 1-128. 
        When referring to a list of General MIDI patches, 1 must be subtracted 
        to play the correct patch. For a full list of General MIDI instruments, 
        see <a href="http://www.midi.org/">
        www.midi.org/about-midi/gm/gm1sound.shtml</a>. 
        The General MIDI channel 10 percussion key map is not relevant to the 
        toneGenerator method because it always defaults to MIDI channel 1.</li>
		<br>
      </td>
  </tr>
  <tr>
    <td><h3>volume (r7)</h3>
      <li>Accepts a positive byte value (0-127) where 127 is the loudest and 0 
        is silent. This value denotes MIDI velocity which refers to the initial 
        attack of the tone.</li>
      <li>If the parameter value is outside this range, it applies a default value 100.</li>
      <li>MIDI velocity measures how hard a <em>note on</em> (or <em>note off</em>) 
        message is played, perhaps on a MIDI controller like a keyboard. Most 
        MIDI synthesizers will translate this into volume on a logarithmic scale 
        in which the difference in amplitude decreases as the velocity value increases.</li>
      <li>Note that velocity value on more sophisticated synthesizers can also 
        affect the timbre of the tone (as most instruments sound different when 
        they are played louder or softer).</li>
      </td>
  </tr>
</table>
System service 31 was developed and documented by Otterbein student Tony Brock in July 2007.

<p></p>
<hr>
<h3>Video Out(Memory Mapped I/O)</h3>
SNUVM simulates a Video Out implemented by Memory Mapped I/O. To turn on video out, we should call #45 system call. More detail information is below.<br>
<br>
1. Address space(Memory mapped I/O)<br>
0xD0000 - 0xD063F ( 80*20 dots; each dot is one byte)<br>
<br>
2. Structure of dot pixel<br>
20 x 80 ASCII characters<br>
<br>
3. To turn on Video Out<br>
SWI #45    @Video On<br>
<br>
4. To turn off Video Out<br>
SWI #46    @Video Off

<p></p>
<hr>
<h3>Example of video and sound output</h3>
The sample ARM9 program below will print strings on the screen and make midi sounds, then close it.
<p>
<pre>
@ Program Description: 
@
@ SNUVM is Seoul National University Assembly-executable Virtual Machine.
@ It assembles several kinds of assembly source files(such as ARM9 and MIPS)
@ and interprets output with built-in OS system-call services.
@ SNUVM is written in Java with eclipse and requires
@ at least Release 1.4 of the J2SE Java Runtime Environment(JRE) to work.
@
@ Author: Jaejin Lee, Jeongho Nah
@ License: MIT License
@ Creation Date: 2009-12-17
@ Revisions: 0
@   -Date: 				-Modified by: 
@
@ Remark:
@	SNUVM was extended from MARS.
@	"MARS Copyright (c) 2003-2009,  Pete Sanderson and Kenneth Vollmar"
@
@===================================
@ ASSEMBLER TEST CODE
@ 17th February 2010
@ Print sample characters to VideoOut and make midi sounds
@===================================
	.code32
start:
	swi #45			@ videoOut on

	mov r0, #0xff
p1:	 mov r0, #0xD
	mov r0, r0, lsl#16	 @set r0 as 0xD0000
	mov r1, #65	 @set r1 as ASCII base
	mov r3, #80	 @rows
	mov r4, #25	 @columns
	mul r2, r3, r4	 @get number of pixels as counter
loop1:	and r1, r1, 0xFF	@mask r1 ASCII base
	mov r5, r1
	mov	r5, r5, lsl #24
	str r5, [r0]	 @set memory address r0, set character color to R=0, G=0, B=0
	add r0, r0, #4	 @0xD0000 + 4 (next address for background color)
	and r1, r1, 0xFF	@mask r1 ASCII base
	mov r5, #0	 @set r5 to zero
	mov r5, r5, lsl #8
	and r6, r2, #0xFF	@r6 as background color
	orr r5, r5, #0x7f	 @set r5 R(color)
	mov r5, r5, lsl #8
	orr r5, r5, r6	 @set r5 G(color)
	mov r5, r5, lsl #8
	orr r5, r5, r6	 @set r5 B(color)
	str r5, [r0]	 @set memory address r0
	
midi1:	mov r9, r4
	mov r10, r5
	mov r11, r6
	mov r12, r7
	and r4, r2, #0xFF	@midi trick using pixel counter
	mov r5, #0
	orr r5, r5, #200
	
	add r6, r4, #1
	mov r7, #64
@	swi #33
	mov r7, r12
	mov r6, r11
	mov r5, r10
	mov r4, r9

	mov r10, r4
	mov r4, #1	 @r0 = 1
	mov r4, r4, lsl #2	 @r0 << 10 means *4
	swi #32	 @sleep
	mov r4, r10

	add r1, r1, #1	 @ASCII base +1
	add r0, r0, #4	 @0xD0000 + 4 (next address)
	sub r2, r2, #1	 @pixel counter -1
	cmp r2, #0	 @is r2 zero?
	bne loop1	 @branch not zero

halt:
	swi #46		@videoOut off
	swi #10		@exit
</pre>
<p></p>

</body>
</html>